"""
管理员用户管理视图
"""
import csv
import io
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAdminUser
from rest_framework.throttling import UserRateThrottle
from django.contrib.auth import get_user_model
from django.db.models import Q, Count, OuterRef, Subquery, IntegerField
from django.db import models
from django.utils import timezone
from datetime import timedelta
from django.http import HttpResponse
from .serializers import UserSerializer, AdminActionLogSerializer
from .models import AdminActionLog
from apps.routes.models import RoutePlan
from apps.attractions.models import Attraction
from apps.social.models import Post

try:
    from openpyxl import Workbook
    from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
    from openpyxl.utils import get_column_letter
    OPENPYXL_AVAILABLE = True
except ImportError:
    OPENPYXL_AVAILABLE = False

User = get_user_model()


class AdminUserViewSet(viewsets.ReadOnlyModelViewSet):
    """管理员用户管理视图集"""
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsAdminUser]
    
    def get_queryset(self):
        """获取用户列表，支持搜索和筛选"""
        queryset = User.objects.all().annotate(
            posts_count=Count('posts', distinct=True),
            comments_count=Count('comments', distinct=True)
        )
        
        # 搜索
        search = self.request.query_params.get('search', None)
        if search:
            queryset = queryset.filter(
                Q(username__icontains=search) |
                Q(email__icontains=search) |
                Q(phone__icontains=search)
            )
        
        # 筛选活跃用户（最近30天有活动）
        active_only = self.request.query_params.get('active_only', None)
        if active_only == 'true':
            thirty_days_ago = timezone.now() - timedelta(days=30)
            active_user_ids = RoutePlan.objects.filter(
                created_at__gte=thirty_days_ago
            ).values_list('user_id', flat=True).distinct()
            queryset = queryset.filter(
                Q(posts__created_at__gte=thirty_days_ago) |
                Q(comments__created_at__gte=thirty_days_ago) |
                Q(id__in=active_user_ids)
            ).distinct()
        
        queryset = queryset.order_by('-created_at')
        
        # 为每个用户添加路线数量（在序列化器中处理会更高效）
        return queryset
    
    def list(self, request, *args, **kwargs):
        """重写list方法，添加路线数量统计"""
        response = super().list(request, *args, **kwargs)
        
        # 获取所有用户ID
        user_ids = [user['id'] for user in response.data.get('results', [])]
        
        # 批量查询路线数量
        route_counts = {}
        if user_ids:
            for route in RoutePlan.objects.filter(user_id__in=user_ids).values('user_id').annotate(count=Count('id')):
                route_counts[route['user_id']] = route['count']
        
        # 为每个用户添加路线数量
        for user in response.data.get('results', []):
            user['routes_count'] = route_counts.get(user['id'], 0)
        
        return response
    
    @action(detail=True, methods=['post'])
    def toggle_active(self, request, pk=None):
        """启用/禁用用户"""
        user = self.get_object()
        user.is_active = not user.is_active
        user.save()
        return Response({
            'message': f'用户已{"启用" if user.is_active else "禁用"}',
            'is_active': user.is_active
        })
    
    @action(detail=True, methods=['delete'])
    def delete(self, request, pk=None):
        """删除用户（软删除：禁用账户）"""
        user = self.get_object()
        if user.is_superuser:
            return Response(
                {'error': '不能删除超级管理员'},
                status=status.HTTP_400_BAD_REQUEST
            )
        user.is_active = False
        user.save()
        return Response({'message': '用户已禁用'})
    
    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取用户统计信息（增强版）"""
        from apps.routes.models import RoutePlan
        from apps.itineraries.models import Itinerary
        
        total_users = User.objects.count()
        active_users = User.objects.filter(is_active=True).count()
        
        # 最近注册用户（7天）
        seven_days_ago = timezone.now() - timedelta(days=7)
        recent_users = User.objects.filter(created_at__gte=seven_days_ago).count()
        
        # 活跃用户（最近30天有活动）
        thirty_days_ago = timezone.now() - timedelta(days=30)
        active_recent = User.objects.filter(
            Q(posts__created_at__gte=thirty_days_ago) |
            Q(comments__created_at__gte=thirty_days_ago) |
            Q(route_plans__created_at__gte=thirty_days_ago) |
            Q(itineraries__created_at__gte=thirty_days_ago)
        ).distinct().count()
        
        # 用户行为统计
        users_with_posts = User.objects.annotate(
            posts_count=Count('posts')
        ).filter(posts_count__gt=0).count()
        
        users_with_routes = RoutePlan.objects.values('user_id').distinct().count()
        
        users_with_itineraries = User.objects.annotate(
            itineraries_count=Count('itineraries')
        ).filter(itineraries_count__gt=0).count()
        
        # 用户注册趋势（最近7天）
        registration_trend = []
        for i in range(7):
            date = timezone.now() - timedelta(days=6-i)
            count = User.objects.filter(
                created_at__date=date.date()
            ).count()
            registration_trend.append({
                'date': date.strftime('%Y-%m-%d'),
                'count': count
            })
        
        return Response({
            'total': total_users,
            'active': active_users,
            'recent': recent_users,
            'active_recent': active_recent,
            'users_with_posts': users_with_posts,
            'users_with_routes': users_with_routes,
            'users_with_itineraries': users_with_itineraries,
            'registration_trend': registration_trend,
            'active_rate': round((active_recent / total_users * 100) if total_users > 0 else 0, 2)
        })


class AdminActionLogViewSet(viewsets.ReadOnlyModelViewSet):
    """管理员操作日志视图集"""
    queryset = AdminActionLog.objects.select_related('admin').all()
    serializer_class = AdminActionLogSerializer
    permission_classes = [IsAdminUser]
    
    def get_queryset(self):
        """获取操作日志列表，支持搜索和筛选"""
        queryset = AdminActionLog.objects.select_related('admin').all()
        
        # 搜索
        search = self.request.query_params.get('search', None)
        if search:
            queryset = queryset.filter(
                Q(admin__username__icontains=search) |
                Q(target_name__icontains=search) |
                Q(description__icontains=search)
            )
        
        # 筛选操作类型
        action = self.request.query_params.get('action', None)
        if action:
            queryset = queryset.filter(action=action)
        
        # 筛选目标类型
        target_type = self.request.query_params.get('target_type', None)
        if target_type:
            queryset = queryset.filter(target_type=target_type)
        
        # 筛选时间范围
        start_date = self.request.query_params.get('start_date', None)
        end_date = self.request.query_params.get('end_date', None)
        if start_date:
            queryset = queryset.filter(created_at__gte=start_date)
        if end_date:
            queryset = queryset.filter(created_at__lte=end_date)
        
        # 筛选管理员
        admin_id = self.request.query_params.get('admin_id', None)
        if admin_id:
            queryset = queryset.filter(admin_id=admin_id)
        
        return queryset.order_by('-created_at')
    
    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取操作日志统计信息"""
        total_logs = AdminActionLog.objects.count()
        
        # 最近7天的日志数
        seven_days_ago = timezone.now() - timedelta(days=7)
        recent_logs = AdminActionLog.objects.filter(created_at__gte=seven_days_ago).count()
        
        # 按操作类型统计
        action_stats = AdminActionLog.objects.values('action').annotate(
            count=Count('id')
        ).order_by('-count')
        
        # 按目标类型统计
        target_stats = AdminActionLog.objects.values('target_type').annotate(
            count=Count('id')
        ).order_by('-count')[:10]  # 前10个
        
        # 按管理员统计
        admin_stats = AdminActionLog.objects.values('admin__username').annotate(
            count=Count('id')
        ).order_by('-count')[:10]  # 前10个
        
        return Response({
            'total': total_logs,
            'recent': recent_logs,
            'action_stats': list(action_stats),
            'target_stats': list(target_stats),
            'admin_stats': list(admin_stats)
        })


class AdminHealthCheckViewSet(viewsets.ViewSet):
    """系统健康检查视图集"""
    permission_classes = [IsAdminUser]
    
    @action(detail=False, methods=['get'])
    def health(self, request):
        """系统健康检查"""
        from apps.utils.monitoring import performance_monitor, error_collector
        from django.db import connection
        from django.core.cache import cache
        import time
        
        health_status = {
            'status': 'healthy',
            'timestamp': timezone.now().isoformat(),
            'checks': {}
        }
        
        # 数据库连接检查
        try:
            connection.ensure_connection()
            db_status = 'healthy'
            db_message = '数据库连接正常'
        except Exception as e:
            db_status = 'unhealthy'
            db_message = f'数据库连接失败: {str(e)}'
            health_status['status'] = 'unhealthy'
        
        health_status['checks']['database'] = {
            'status': db_status,
            'message': db_message
        }
        
        # 缓存检查
        try:
            test_key = 'health_check_test'
            cache.set(test_key, 'test', 10)
            cache_result = cache.get(test_key)
            if cache_result == 'test':
                cache_status = 'healthy'
                cache_message = '缓存服务正常'
            else:
                cache_status = 'degraded'
                cache_message = '缓存服务异常'
        except Exception as e:
            cache_status = 'unhealthy'
            cache_message = f'缓存服务失败: {str(e)}'
            health_status['status'] = 'unhealthy'
        
        health_status['checks']['cache'] = {
            'status': cache_status,
            'message': cache_message
        }
        
        # 性能统计
        db_stats = performance_monitor.get_database_statistics()
        error_stats = error_collector.get_error_statistics(hours=24)
        
        health_status['performance'] = {
            'database_queries': db_stats.get('total_queries', 0),
            'database_avg_time': round(db_stats.get('avg_time', 0) * 1000, 2),  # 转换为毫秒
            'errors_last_24h': error_stats.get('total_errors', 0),
            'error_types': error_stats.get('error_types', {})
        }
        
        return Response(health_status)


class ExportThrottle(UserRateThrottle):
    """数据导出限流（更严格的限制）"""
    rate = '10/hour'  # 每小时10次


class AdminExportViewSet(viewsets.ViewSet):
    """管理员数据导出视图集"""
    permission_classes = [IsAdminUser]
    throttle_classes = [ExportThrottle]  # 应用限流
    
    @action(detail=False, methods=['post'])
    def export_data(self, request):
        """
        导出数据（增强错误处理和验证）
        :param request.data: {type: 'attractions'|'users'|'posts'|'routes', format: 'excel'|'csv'}
        """
        try:
            export_type = request.data.get('type', 'attractions')
            export_format = request.data.get('format', 'csv')
            
            # 验证导出类型
            valid_types = ['attractions', 'users', 'posts', 'routes']
            if export_type not in valid_types:
                return Response({
                    'error': '不支持的导出类型',
                    'details': f'支持的类型: {", ".join(valid_types)}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证导出格式
            valid_formats = ['excel', 'csv']
            if export_format not in valid_formats:
                return Response({
                    'error': '不支持的导出格式',
                    'details': f'支持的格式: {", ".join(valid_formats)}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 执行导出
            if export_type == 'attractions':
                return self._export_attractions(export_format)
            elif export_type == 'users':
                return self._export_users(export_format)
            elif export_type == 'posts':
                return self._export_posts(export_format)
            elif export_type == 'routes':
                return self._export_routes(export_format)
        except Exception as e:
            import logging
            logger = logging.getLogger(__name__)
            logger.error(f'数据导出失败: {str(e)}', exc_info=True)
            return Response({
                'error': '数据导出失败',
                'details': str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def _export_attractions(self, format_type):
        """导出景点数据"""
        attractions = Attraction.objects.all().order_by('-created_at')
        
        if format_type == 'csv':
            response = HttpResponse(content_type='text/csv; charset=utf-8-sig')
            response['Content-Disposition'] = 'attachment; filename="attractions.csv"'
            
            writer = csv.writer(response)
            writer.writerow(['ID', '名称', '分类', '地址', '门票价格', '评分', '热度', '创建时间'])
            
            for attr in attractions:
                writer.writerow([
                    attr.id,
                    attr.name,
                    attr.get_category_display(),
                    attr.address or '',
                    float(attr.ticket_price),
                    float(attr.rating),
                    attr.popularity,
                    attr.created_at.strftime('%Y-%m-%d %H:%M:%S')
                ])
            
            return response
        elif format_type == 'excel' and OPENPYXL_AVAILABLE:
            return self._export_to_excel(
                attractions,
                ['ID', '名称', '分类', '地址', '门票价格', '评分', '热度', '创建时间'],
                lambda attr: [
                    attr.id,
                    attr.name,
                    attr.get_category_display(),
                    attr.address or '',
                    float(attr.ticket_price),
                    float(attr.rating),
                    attr.popularity,
                    attr.created_at.strftime('%Y-%m-%d %H:%M:%S')
                ],
                'attractions'
            )
        else:
            # Excel格式不可用时，返回CSV
            return self._export_attractions('csv')
    
    def _export_users(self, format_type):
        """导出用户数据"""
        users = User.objects.all().order_by('-created_at')
        
        if format_type == 'csv':
            response = HttpResponse(content_type='text/csv; charset=utf-8-sig')
            response['Content-Disposition'] = 'attachment; filename="users.csv"'
            
            writer = csv.writer(response)
            writer.writerow(['ID', '用户名', '邮箱', '手机号', '是否活跃', '创建时间', '最后登录'])
            
            for user in users:
                writer.writerow([
                    user.id,
                    user.username,
                    user.email or '',
                    user.phone or '',
                    '是' if user.is_active else '否',
                    user.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                    user.last_login.strftime('%Y-%m-%d %H:%M:%S') if user.last_login else ''
                ])
            
            return response
        elif format_type == 'excel' and OPENPYXL_AVAILABLE:
            return self._export_to_excel(
                users,
                ['ID', '用户名', '邮箱', '手机号', '是否活跃', '创建时间', '最后登录'],
                lambda user: [
                    user.id,
                    user.username,
                    user.email or '',
                    user.phone or '',
                    '是' if user.is_active else '否',
                    user.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                    user.last_login.strftime('%Y-%m-%d %H:%M:%S') if user.last_login else ''
                ],
                'users'
            )
        else:
            return self._export_users('csv')
    
    def _export_posts(self, format_type):
        """导出动态数据"""
        posts = Post.objects.select_related('user').all().order_by('-created_at')
        
        if format_type == 'csv':
            response = HttpResponse(content_type='text/csv; charset=utf-8-sig')
            response['Content-Disposition'] = 'attachment; filename="posts.csv"'
            
            writer = csv.writer(response)
            writer.writerow(['ID', '用户', '内容', '点赞数', '评论数', '创建时间'])
            
            for post in posts:
                writer.writerow([
                    post.id,
                    post.user.username,
                    post.content[:100] if post.content else '',  # 限制长度
                    post.likes_count,
                    post.comments_count,
                    post.created_at.strftime('%Y-%m-%d %H:%M:%S')
                ])
            
            return response
        elif format_type == 'excel' and OPENPYXL_AVAILABLE:
            return self._export_to_excel(
                posts,
                ['ID', '用户', '内容', '点赞数', '评论数', '创建时间'],
                lambda post: [
                    post.id,
                    post.user.username,
                    post.content[:100] if post.content else '',  # 限制长度
                    post.likes_count,
                    post.comments_count,
                    post.created_at.strftime('%Y-%m-%d %H:%M:%S')
                ],
                'posts'
            )
        else:
            return self._export_posts('csv')
    
    def _export_routes(self, format_type):
        """导出路线数据"""
        routes = RoutePlan.objects.select_related('user', 'start_attraction').all().order_by('-created_at')
        
        if format_type == 'csv':
            response = HttpResponse(content_type='text/csv; charset=utf-8-sig')
            response['Content-Disposition'] = 'attachment; filename="routes.csv"'
            
            writer = csv.writer(response)
            writer.writerow(['ID', '用户', '起始景点', '预算', '总费用', '总距离', '创建时间'])
            
            for route in routes:
                writer.writerow([
                    route.id,
                    route.user.username if route.user else '游客',
                    route.start_attraction.name if route.start_attraction else '',
                    float(route.budget),
                    float(route.total_cost) if route.total_cost else 0,
                    float(route.total_distance) if route.total_distance else 0,
                    route.created_at.strftime('%Y-%m-%d %H:%M:%S')
                ])
            
            return response
        elif format_type == 'excel' and OPENPYXL_AVAILABLE:
            return self._export_to_excel(
                routes,
                ['ID', '用户', '起始景点', '预算', '总费用', '总距离', '创建时间'],
                lambda route: [
                    route.id,
                    route.user.username if route.user else '游客',
                    route.start_attraction.name if route.start_attraction else '',
                    float(route.budget),
                    float(route.total_cost) if route.total_cost else 0,
                    float(route.total_distance) if route.total_distance else 0,
                    route.created_at.strftime('%Y-%m-%d %H:%M:%S')
                ],
                'routes'
            )
        else:
            return self._export_routes('csv')
    
    def _export_to_excel(self, queryset, headers, row_data_func, filename_prefix):
        """导出数据到Excel格式"""
        if not OPENPYXL_AVAILABLE:
            return Response(
                {'error': 'Excel导出功能不可用，请安装openpyxl库'},
                status=status.HTTP_503_SERVICE_UNAVAILABLE
            )
        
        wb = Workbook()
        ws = wb.active
        ws.title = '数据导出'
        
        # 设置样式
        header_font = Font(bold=True, color='FFFFFF')
        header_fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')
        header_alignment = Alignment(horizontal='center', vertical='center')
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )
        
        # 写入表头
        for col_idx, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col_idx, value=header)
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
            cell.border = border
        
        # 写入数据
        for row_idx, item in enumerate(queryset, 2):
            row_data = row_data_func(item)
            for col_idx, value in enumerate(row_data, 1):
                cell = ws.cell(row=row_idx, column=col_idx, value=value)
                cell.border = border
                if col_idx == 1:  # ID列居中
                    cell.alignment = Alignment(horizontal='center')
        
        # 自动调整列宽
        for col_idx, header in enumerate(headers, 1):
            max_length = len(str(header))
            for row_idx in range(2, ws.max_row + 1):
                cell_value = ws.cell(row=row_idx, column=col_idx).value
                if cell_value:
                    max_length = max(max_length, len(str(cell_value)))
            ws.column_dimensions[get_column_letter(col_idx)].width = min(max_length + 2, 50)
        
        # 冻结首行
        ws.freeze_panes = 'A2'
        
        # 保存到内存
        output = io.BytesIO()
        wb.save(output)
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(
            output.getvalue(),
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = f'attachment; filename="{filename_prefix}.xlsx"'
        
        return response

